#include "Life.h"

unsigned int Life::GetCountOfNeighbores(int ci, int cj)
{
	unsigned int count = 0;

	int left = ( ( ci - (int)this->radius ) >= 0 ) ? ( ci - this->radius ) : 0;
	int right = ( ( ci + (int)this->radius + 1 ) <= this->width ) ? ( ci + this->radius + 1 ) : this->width;
	int top = ( ( cj - (int)this->radius ) >= 0 ) ? ( cj - this->radius ) : 0;
	int bottom = ( ( cj + (int)this->radius + 1 ) <= this->height ) ? ( cj + this->radius + 1 ) : this->height;

	for ( int i = left; i < right; i++ )
		for ( int j = top; j < bottom; j++ )
			count += this->life[i][j] ? 1 : 0;

	count -= this->life[ci][cj] ? 1 : 0;

	return count;
}

void Life::Step()
{
	int NeiCount;
	bool** tempLife = new bool* [this->height];
	for (unsigned int i=0; i<this->height; i++)	
		tempLife[i] = new bool [this->width];

	for (int i=0; i<this->width; i++)
		for (int j=0; j<this->height; j++)
		{
			NeiCount = this->GetCountOfNeighbores(i,j);
			if(!this->life[i][j])
			{
				if ( (NeiCount >= this->birth->GetMin()) && (NeiCount <= this->birth->GetMax()) )
				{ tempLife[i][j] = true; }
				else{ tempLife[i][j] = false; }
			}
			else 
			{
				if (NeiCount >= this->live->GetMin() && NeiCount <= this->live->GetMax())			
				{ tempLife[i][j] = true; }
				else{ tempLife[i][j] = false; }
			}				
		}
	for (unsigned int i=0; i<this->height; i++)	
		delete [] this->life[i];	
	delete [] this->life;
	this->life = tempLife;
	tempLife = NULL;
}

Life::Life (char* fileName, unsigned int width , unsigned int height)
{
	this->Load(fileName);
	this->width = width;
	this->height = height;
	this->life = new bool* [height];
	for (unsigned int i=0; i<height; i++)	
		life[i] = new bool [width];
	for (unsigned int i=0; i<width; i++)
		for(unsigned int j=0; j<height; j++)			
			life[i][j]=false;
}

bool Life::Load (char* fileName)
{	
	char *attr, *val;
	FILE* cfgFile = fopen(fileName, "r");	
	if ( cfgFile == NULL ) return false;

	attr = new char[255];
	val = new char[255];	

	while (!feof(cfgFile))
	{
		fscanf(cfgFile, "%s = %s", attr, val);

		if (!strcmp(attr, "TYPE"))
		{
			this->type = TYPICAL;
			if ( !strcmp(val, "block") )
				this->type = BLOCK;
			if ( !strcmp(val, "random") )
				this->type = RANDOM;
		}

		if ( !strcmp(attr, "RADIUS") )
			this->radius = atoi(val);

		if ( !strcmp(attr, "LIVE") )
		{
			int l, r;
			sscanf(val, "%d-%d", &l, &r);
			this->live = new Condition(r, l);
		}

		if ( !strcmp(attr, "BIRTH") )
		{
			int l, r;
			sscanf(val, "%d-%d", &l, &r);
			this->birth = new Condition(r, l);
		}

		if ( !strcmp(attr, "BIRTH_CHANCE") )
			this->birthChance = atoi(val);

		if ( !strcmp(attr, "DEATH_CHANCE") )
			this->deathChance = atoi(val);
	}

	fclose(cfgFile);
	delete [] attr;
	delete [] val;
	return true;
}